public class 矩阵中和能被K整除的路径 {
    public static int mod = 1000000007;
    public int numberOfPaths(int[][] grid, int k) {
        return dfs(grid,0,0,0,k);
    }

    private int dfs(int[][] grid, int i, int j, int r, int k) {
        if (i == grid.length - 1 && j == grid[0].length - 1) {
            if ((r + grid[i][j]) % k == 0) {
                return 1;
            } else {
                return 0;
            }
        }
        int ans = 0;
        // 向下走
        if (i + 1 < grid.length) {
            ans += dfs(grid,i + 1,j,((grid[i][j] + r) % k),k) % mod;
        }
        if (j + 1 < grid[0].length) {
            ans += dfs(grid,i,j + 1,((grid[i][j] + r) % k),k) % mod;
        }
        return ans;
    }

    public int numberOfPaths1(int[][] grid, int k) {
        int[][][] dp = new int[grid.length][grid[0].length][k];
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                for (int l = 0; l < k; l++) {
                    dp[i][j][l] = -1;
                }
            }
        }
        return dfs1(grid,0,0,0,k,dp);
    }

    private int dfs1(int[][] grid, int i, int j, int r, int k,int[][][] dp) {
        if (i == grid.length - 1 && j == grid[0].length - 1) {
            if ((r + grid[i][j]) % k == 0) {
                return 1;
            } else {
                return 0;
            }
        }
        if (dp[i][j][r] != -1) {
            return dp[i][j][r];
        }
        int ans = 0;
        // 向下走
        if (i + 1 < grid.length) {
            ans = (ans +  dfs1(grid,i + 1,j,((grid[i][j] + r) % k),k,dp) % mod) % mod;
        }
        if (j + 1 < grid[0].length) {
            ans = (ans + dfs1(grid,i,j + 1,((grid[i][j] + r) % k),k,dp) % mod) % mod;
        }
        dp[i][j][r] = ans;
        return ans;
    }

    public int numberOfPaths2(int[][] grid, int k) {
        int[][][] dp = new int[grid.length][grid[0].length][k];
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                for (int l = 0; l < k; l++) {
                    dp[i][j][l] = -1;
                }
            }
        }
        return dfs1(grid,0,0,0,k,dp);
    }
}
